/*
 * Created on 2006-3-15
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package auditoryUIbk;
import java.util.*;
import java.awt.*;
import java.text.*;

/**
 * @author Shengdong Zhao
 * 
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class ContinuousControl {
	
	public static final boolean CLOCKWISE = true;
	public static final boolean ANTICLOCKWISE = false;

	private static final int DEFAULT_HISTORY = 5;

	private static ArrayList points = new ArrayList();

	private static int history = DEFAULT_HISTORY;
	
	private static int minAngleCap = 10;
	private static int maxAngle = 100;
	private static int maxAngleCap = 140;
	
	
	public static void addPoint(Point p){
	    if(points.size() < history)
        {
	    	points.add(p);
            return;
        }
		else{
			//we keep a constant number of points in the list 
			points.remove(0);
			points.add(p);
		}
	}
	
	public static void clearPoints(){
		points.clear();
	}
	
    public static double getCurveChange()
    {
        if(points.size() < history)
        {
            return 0.0;
        }
        
        Point point = (Point)points.get(0);
        Point point1 = (Point)points.get(history / 2);
        Point point2 = (Point)points.get(history - 1);
        
        double d = getAngle(point, point1, point2);
        DecimalFormat decimalformat = new DecimalFormat("000.000");
        if(d < (double)minAngleCap || d > (double)maxAngleCap)
            return 0.0;
        if(d > (double)maxAngle)
            d = maxAngle;
        
        return d;
    }
    
    public static boolean getDirection(){
    	if(points.size() < history)
        {
            return false;
        }
        
        Point point = (Point)points.get(0);
        Point point1 = (Point)points.get(history / 2);
        Point point2 = (Point)points.get(history - 1);
        double d = getAngle(point, point1, point2);
        return getDirection(point, point1, point2, d);
    }

    /**
     * Get the angle of the three points
     * @param point
     * @param point1
     * @param point2
     * @return angle in Degrees 
     */
    public static double getAngle(Point point, Point point1, Point point2)
    {
        Point point3 = new Point(point1.x - point.x, point1.y - point.y);
        Point point4 = new Point(point2.x - point1.x, point2.y - point1.y);
        double d = point3.x * point4.x + point3.y * point4.y;
        double d1 = getLength(point, point1);
        double d2 = getLength(point1, point2);
        double d3 = Math.toDegrees(Math.acos(d / (d1 * d2)));
        return d3;
    }

    /**
     * get the length between the two points
     * @param point
     * @param point1
     * @return length in pixels
     */
    public static double getLength(Point point, Point point1)
    {
        double d = Math.abs(point.x - point1.x);
        double d1 = Math.abs(point.y - point1.y);
        return Math.sqrt(d * d + d1 * d1);
    }

    /**
     * get which direction the circular movement is, whether it's moving 
     * clockwise or counterclockwise 
     * 
     * @param point
     * @param point1
     * @param point2
     * @param d
     * @return either clockwise or counter clockwise
     */
    private static boolean getDirection(Point point, Point point1, Point point2, double d)
    {
        Point point3 = new Point(point1.x - point.x, point1.y - point.y);
        Point point4 = new Point(point2.x - point1.x, point2.y - point1.y);
        double d1 = point3.getX() * point4.getY() - point4.getX() * point3.getY();
        boolean flag;
        if(d1 > 0.0D)
            flag = true;
        else
            flag = false;
        return flag;
    }
	

}
